const express = require('express');
const router = express.Router();
const multer = require('multer');
const path = require('path');
const fs = require('fs');
const archiver = require('archiver');
const Photo = require('../models/Photo');
const Album = require('../models/Album');
const auth = require('../middleware/auth');
const crypto = require('crypto');
const sharp = require('sharp');
const { exec } = require('child_process');
const util = require('util');
const execPromise = util.promisify(exec);
const Jimp = require('jimp');
const gm = require('gm');
const { v4: uuidv4 } = require('uuid');

// 确保上传目录存在
const uploadDir = path.join(__dirname, '../uploads');
const thumbnailsDir = path.join(__dirname, '../uploads/thumbnails');
const previewsDir = path.join(__dirname, '../uploads/previews');

// 创建年月日目录结构
const createDateDirs = () => {
  const date = new Date();
  const year = date.getFullYear();
  const month = String(date.getMonth() + 1).padStart(2, '0');
  const day = String(date.getDate()).padStart(2, '0');
  
  const yearDir = path.join(uploadDir, year.toString());
  const monthDir = path.join(yearDir, month);
  const dayDir = path.join(monthDir, day);
  
  [yearDir, monthDir, dayDir].forEach(dir => {
    if (!fs.existsSync(dir)) {
      fs.mkdirSync(dir, { recursive: true });
    }
  });
  
  return dayDir;
};

// 创建缩略图目录
const createThumbnailDirs = () => {
  const date = new Date();
  const year = date.getFullYear();
  const month = String(date.getMonth() + 1).padStart(2, '0');
  const day = String(date.getDate()).padStart(2, '0');
  
  const yearDir = path.join(thumbnailsDir, year.toString());
  const monthDir = path.join(yearDir, month);
  const dayDir = path.join(monthDir, day);
  
  [yearDir, monthDir, dayDir].forEach(dir => {
    if (!fs.existsSync(dir)) {
      fs.mkdirSync(dir, { recursive: true });
    }
  });
  
  return dayDir;
};

// 创建预览图目录
const createPreviewDirs = () => {
  const date = new Date();
  const year = date.getFullYear();
  const month = String(date.getMonth() + 1).padStart(2, '0');
  const day = String(date.getDate()).padStart(2, '0');
  
  const yearDir = path.join(previewsDir, year.toString());
  const monthDir = path.join(yearDir, month);
  const dayDir = path.join(monthDir, day);
  
  [yearDir, monthDir, dayDir].forEach(dir => {
    if (!fs.existsSync(dir)) {
      fs.mkdirSync(dir, { recursive: true });
    }
  });
  
  return dayDir;
};

// 生成安全的文件名
const generateSafeFilename = (originalname) => {
  const timestamp = Date.now();
  const randomString = crypto.randomBytes(8).toString('hex');
  const ext = path.extname(originalname).toLowerCase();
  return `${timestamp}-${randomString}${ext}`;
};

// 配置 multer 存储
const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    const uploadPath = createDateDirs();
    cb(null, uploadPath);
  },
  filename: function (req, file, cb) {
    cb(null, generateSafeFilename(file.originalname));
  }
});

const upload = multer({ 
  storage: storage,
  limits: {
    fileSize: 20 * 1024 * 1024 // 20MB
  },
  fileFilter: (req, file, cb) => {
    // 检查文件类型
    const allowedTypes = [
      'image/jpeg',
      'image/png',
      'image/gif',
      'image/webp',
      'image/bmp',
      'image/tiff',
      'image/svg+xml'
    ];
    
    if (!allowedTypes.includes(file.mimetype)) {
      return cb(new Error('只支持 JPG、PNG、GIF、WebP、BMP、TIFF 和 SVG 格式的图片'));
    }
    cb(null, true);
  }
});

// 生成缩略图
async function generateThumbnail(filePath, thumbnailPath) {
  try {
    const fileExt = path.extname(filePath).toLowerCase();
    const isBmp = fileExt === '.bmp';
    const isJpg = fileExt === '.jpg' || fileExt === '.jpeg';
    const isSvg = fileExt === '.svg';

    if (isSvg) {
      // SVG文件直接复制，不进行缩放
      await fs.promises.copyFile(filePath, thumbnailPath);
      return true;
    }

    if (isBmp) {
      try {
        // 使用GraphicsMagick处理BMP
        await new Promise((resolve, reject) => {
          gm(filePath)
            .resize(300, 300, '!')
            .quality(80)
            .write(thumbnailPath, (err) => {
              if (err) reject(err);
              else resolve();
            });
        });
      } catch (gmError) {
        console.warn('GraphicsMagick处理BMP失败，尝试使用Jimp:', gmError.message);
        // 如果GraphicsMagick失败，使用Jimp作为备选
        const image = await Jimp.read(filePath);
        await image
          .resize(300, 300, Jimp.RESIZE_BILINEAR)
          .quality(80)
          .writeAsync(thumbnailPath);
      }
    } else if (isJpg) {
      // 针对JPG文件优化Sharp配置
      await sharp(filePath)
        .resize(300, 300, {
          fit: 'inside',
          withoutEnlargement: true
        })
        .jpeg({
          quality: 80,
          progressive: true,
          mozjpeg: true
        })
        .toFile(thumbnailPath);
    } else {
      // 对于其他格式使用Sharp
      await sharp(filePath)
        .resize(300, 300, {
          fit: 'inside',
          withoutEnlargement: true
        })
        .jpeg({
          quality: 80,
          progressive: true
        })
        .toFile(thumbnailPath);
    }

    // 验证生成的缩略图
    const stats = await fs.promises.stat(thumbnailPath);
    if (stats.size === 0) {
      throw new Error('生成的缩略图大小为0');
    }

    return true;
  } catch (error) {
    console.error('生成缩略图失败:', error);
    throw error;
  }
}

// 生成预览图
const generatePreview = async (filePath, filename) => {
  try {
    const fileExt = path.extname(filename).toLowerCase();
    const isSvg = fileExt === '.svg';
    
    // 根据当前日期构建预览图的目标路径
    const date = new Date();
    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, '0');
    const day = String(date.getDate()).padStart(2, '0');
    
    const previewDateDir = path.join(previewsDir, year.toString(), month, day);
    
    // 确保预览图的日期目录存在
    if (!fs.existsSync(previewDateDir)) {
      fs.mkdirSync(previewDateDir, { recursive: true });
    }

    const previewPath = path.join(previewDateDir, filename);

    if (isSvg) {
      // SVG文件直接复制，不进行缩放
      await fs.promises.copyFile(filePath, previewPath);
      return true;
    }
    
    // 读取文件
    const buffer = await fs.promises.readFile(filePath);
    
    // 检查文件类型
    const isBmp = fileExt === '.bmp';
    const isTransparent = fileExt === '.png' || fileExt === '.gif' || fileExt === '.webp';
    
    try {
      if (isBmp) {
        // 使用GraphicsMagick处理BMP
        await new Promise((resolve, reject) => {
          gm(filePath)
            .resize(1200, 1200, '!')
            .quality(85)
            .write(previewPath, (err) => {
              if (err) reject(err);
              else resolve();
            });
        });
      } else {
        // 使用sharp处理其他格式
        const sharpInstance = sharp(buffer, {
          failOnError: false,
          limitInputPixels: false,
          sequentialRead: true,
          density: 300
        });

        if (isTransparent) {
          await sharpInstance
            .resize(1200, 1200, {
              fit: 'inside',
              withoutEnlargement: true
            })
            .png({
              quality: 90,
              compressionLevel: 9
            })
            .toFile(previewPath);
        } else {
          await sharpInstance
            .resize(1200, 1200, {
              fit: 'inside',
              withoutEnlargement: true
            })
            .jpeg({
              quality: 85,
              chromaSubsampling: '4:2:0',
              mozjpeg: true
            })
            .toFile(previewPath);
        }
      }
    } catch (error) {
      console.warn('主要处理方式失败，尝试使用Jimp:', error.message);
      
      // 如果主要处理方式失败，使用Jimp作为备选
      try {
        const image = await Jimp.read(buffer);
        await image
          .resize(1200, Jimp.AUTO)
          .quality(90)
          .writeAsync(previewPath);
      } catch (jimpError) {
        console.error('Jimp处理也失败:', filename, jimpError.message);
        throw new Error('图片处理失败');
      }
    }

    // 验证生成的预览图
    const previewStats = await fs.promises.stat(previewPath);
    
    if (previewStats.size === 0) {
      throw new Error('生成的预览图大小为0');
    }

    return true;
  } catch (error) {
    console.error('生成预览图失败:', error);
    return false;
  }
};

// 清理过期文件
const cleanupOldFiles = async () => {
  try {
    const thirtyDaysAgo = new Date();
    thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);

    // 查找30天前的照片
    const oldPhotos = await Photo.find({
      createdAt: { $lt: thirtyDaysAgo },
      isDeleted: true
    });

    // 删除文件
    for (const photo of oldPhotos) {
      const filePath = path.join(uploadDir, photo.filename);
      const thumbnailPath = path.join(thumbnailsDir, photo.filename);
      
      [filePath, thumbnailPath].forEach(path => {
        if (fs.existsSync(path)) {
          fs.unlinkSync(path);
        }
      });

      // 删除数据库记录
      await Photo.deleteOne({ _id: photo._id });
    }
  } catch (error) {
    console.error('清理过期文件失败:', error);
  }
};

// 定期清理过期文件（每天执行一次）
setInterval(cleanupOldFiles, 24 * 60 * 60 * 1000);

// 清空回收站
router.delete('/clear-trash', auth, async (req, res) => {
  try {
    // 1. 查找所有已删除的照片
    const photos = await Photo.find({ 
      user: req.user._id,
      isDeleted: true 
    });

    // 2. 删除照片文件
    for (const photo of photos) {
      const filePath = path.join(__dirname, '../uploads', photo.datePath, photo.filename);
      const thumbnailPath = path.join(__dirname, '../uploads/thumbnails', photo.datePath, photo.filename);
      const previewPath = path.join(__dirname, '../uploads/previews', photo.datePath, photo.filename);
      
      try {
        if (fs.existsSync(filePath)) {
          fs.unlinkSync(filePath);
        }
        if (fs.existsSync(thumbnailPath)) {
          fs.unlinkSync(thumbnailPath);
        }
        if (fs.existsSync(previewPath)) {
          fs.unlinkSync(previewPath);
        }
      } catch (fileError) {
        console.error('删除照片文件失败:', fileError);
      }
    }

    // 3. 删除照片记录
    const deletedPhotos = await Photo.deleteMany({ 
      user: req.user._id,
      isDeleted: true 
    });

    // 4. 删除相册记录
    const deletedAlbums = await Album.deleteMany({
      user: req.user._id,
      isDeleted: true
    });

    res.json({ 
      message: '回收站已清空',
      deletedPhotos: deletedPhotos.deletedCount,
      deletedAlbums: deletedAlbums.deletedCount
    });
  } catch (error) {
    console.error('清空回收站失败:', error);
    res.status(500).json({ message: '清空回收站失败: ' + error.message });
  }
});

// 获取照片列表
router.get('/', auth, async (req, res) => {
  try {
    const { albumId } = req.query;
    const query = { 
      user: req.user.id,
      isDeleted: false  // 只获取未删除的照片
    };
    if (albumId) {
      query.album = albumId;
    }
    const photos = await Photo.find(query).sort({ createdAt: -1 });
    res.json(photos);
  } catch (error) {
    console.error('获取照片列表失败:', error);
    res.status(500).json({ message: '获取照片失败' });
  }
});

// 获取回收站照片
router.get('/trash', auth, async (req, res) => {
  try {
    const { albumId } = req.query;
    const query = {
      user: req.user._id,
      isDeleted: true
    };
    
    if (albumId) {
      query.album = albumId;
    }
    
    const photos = await Photo.find(query).sort({ deletedAt: -1 });
    res.json(photos);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// 删除照片
router.delete('/:id', auth, async (req, res) => {
  try {
    // 验证 ID 格式
    if (!req.params.id || !/^[0-9a-fA-F]{24}$/.test(req.params.id)) {
      return res.status(400).json({ message: '无效的照片ID' });
    }

    const photo = await Photo.findOne({ _id: req.params.id, user: req.user.id });
    if (!photo) {
      return res.status(404).json({ message: '照片不存在' });
    }

    // 软删除照片
    photo.isDeleted = true;
    photo.deletedAt = new Date();
    await photo.save();
    
    res.json({ message: '照片已移入回收站' });
  } catch (error) {
    console.error('删除照片失败:', error);
    res.status(500).json({ message: '删除失败' });
  }
});

// 恢复照片
router.post('/:id/restore', auth, async (req, res) => {
  try {
    const photo = await Photo.findOne({
      _id: req.params.id,
      user: req.user._id,
      isDeleted: true
    });

    if (!photo) {
      return res.status(404).json({ error: '照片不存在' });
    }

    photo.isDeleted = false;
    photo.deletedAt = null;
    await photo.save();

    res.json({ message: '照片已恢复' });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// 永久删除照片
router.delete('/:id/permanent', auth, async (req, res) => {
  try {
    // 验证 ID 格式
    if (!req.params.id || !/^[0-9a-fA-F]{24}$/.test(req.params.id)) {
      return res.status(400).json({ message: '无效的照片ID' });
    }

    const photo = await Photo.findOne({
      _id: req.params.id,
      user: req.user._id,
      isDeleted: true
    });

    if (!photo) {
      return res.status(404).json({ message: '照片不存在' });
    }

    // 删除原图、缩略图、预览图
    const filePath = path.join(uploadDir, photo.datePath, photo.filename);
    const thumbnailPath = path.join(thumbnailsDir, photo.datePath, photo.filename);
    const previewPath = path.join(previewsDir, photo.datePath, photo.filename);
    try {
      if (fs.existsSync(filePath)) {
        fs.unlinkSync(filePath);
      }
      if (fs.existsSync(thumbnailPath)) {
        fs.unlinkSync(thumbnailPath);
      }
      if (fs.existsSync(previewPath)) {
        fs.unlinkSync(previewPath);
      }
      // 删除数据库记录
      await Photo.deleteOne({ _id: photo._id });
      res.json({ message: '照片已永久删除' });
    } catch (fileError) {
      console.error('删除文件失败:', fileError);
      // 即使文件删除失败，也继续删除数据库记录
      await Photo.deleteOne({ _id: photo._id });
      res.json({ message: '照片记录已删除，但部分文件可能未完全清理' });
    }
  } catch (error) {
    console.error('永久删除照片失败:', error);
    res.status(500).json({ message: '删除失败' });
  }
});

// 下载单张照片
router.get('/download/:id', auth, async (req, res) => {
  try {
    const photo = await Photo.findOne({ _id: req.params.id, user: req.user.id });
    if (!photo) {
      return res.status(404).json({ message: '照片不存在' });
    }

    const filePath = path.join(uploadDir, photo.filename);
    if (!fs.existsSync(filePath)) {
      return res.status(404).json({ message: '文件不存在' });
    }

    res.download(filePath, photo.originalName);
  } catch (error) {
    console.error('下载照片失败:', error);
    res.status(500).json({ message: '下载失败' });
  }
});

// 批量下载照片
router.post('/download-multiple', auth, async (req, res) => {
  try {
    const { photoIds } = req.body;
    if (!photoIds || !Array.isArray(photoIds)) {
      return res.status(400).json({ message: '无效的请求' });
    }

    const photos = await Photo.find({
      _id: { $in: photoIds },
      user: req.user.id
    });

    if (photos.length === 0) {
      return res.status(404).json({ message: '没有找到照片' });
    }

    const archiver = require('archiver');
    const archive = archiver('zip', {
      zlib: { level: 9 }
    });

    res.attachment('photos.zip');
    archive.pipe(res);

    photos.forEach(photo => {
      const filePath = path.join(uploadDir, photo.datePath, photo.filename);
      if (fs.existsSync(filePath)) {
        archive.file(filePath, { name: photo.originalName });
      }
    });

    await archive.finalize();
  } catch (error) {
    console.error('批量下载照片失败:', error);
    res.status(500).json({ message: '下载失败' });
  }
});

// 修改照片名称
router.patch('/:id/rename', auth, async (req, res) => {
  try {
    const { newName } = req.body;
    if (!newName || typeof newName !== 'string' || newName.trim() === '') {
      return res.status(400).json({ message: '新名称不能为空' });
    }

    const photo = await Photo.findOne({ _id: req.params.id, user: req.user.id });
    if (!photo) {
      return res.status(404).json({ message: '照片不存在' });
    }

    photo.originalName = newName.trim();
    await photo.save();

    res.json(photo);
  } catch (error) {
    console.error('修改照片名称失败:', error);
    res.status(500).json({ message: '修改失败' });
  }
});

// 上传多张照片
router.post('/upload-multiple', auth, upload.array('photos', 20), async (req, res) => {
  const uploadedFiles = [];
  const results = {
    success: [],
    failed: []
  };
  
  try {
    if (!req.files || req.files.length === 0) {
      return res.status(400).json({ message: '没有上传文件' });
    }

    const { albumId } = req.body;
    if (!albumId) {
      return res.status(400).json({ message: '请选择相册' });
    }

    const album = await Album.findOne({ _id: albumId, user: req.user.id });
    if (!album) {
      return res.status(404).json({ message: '相册不存在' });
    }

    // 并行处理所有照片
    const photos = await Promise.all(req.files.map(async (file) => {
      try {
        // 生成缩略图
        const thumbnailDir = createThumbnailDirs();
        const thumbnailPath = path.join(thumbnailDir, file.filename);
        const thumbnailSuccess = await generateThumbnail(file.path, thumbnailPath);
        if (!thumbnailSuccess) {
          throw new Error('处理图片失败');
        }

        // 生成预览图
        const previewSuccess = await generatePreview(file.path, file.filename);
        if (!previewSuccess) {
          throw new Error('处理图片失败');
        }

        const photo = new Photo({
          filename: file.filename,
          originalName: Buffer.from(file.originalname, 'latin1').toString('utf8'),
          datePath: path.relative(uploadDir, path.dirname(file.path)).replace(/\\/g, '/'),
          album: albumId,
          user: req.user.id,
          path: file.path,
          size: file.size,
          mimeType: file.mimetype
        });

        const savedPhoto = await photo.save();
        uploadedFiles.push(file.path);
        results.success.push(savedPhoto);
        return savedPhoto;
      } catch (error) {
        results.failed.push({
          filename: file.originalname,
          error: error.message
        });
        // 如果处理失败，删除已上传的文件
        if (file.path && fs.existsSync(file.path)) {
          fs.unlinkSync(file.path);
        }
        throw error;
      }
    }));

    res.json({
      message: '上传完成',
      results: {
        success: results.success,
        failed: results.failed
      }
    });
  } catch (error) {
    // 如果上传失败，清理已上传的文件
    uploadedFiles.forEach(filePath => {
      if (filePath && fs.existsSync(filePath)) {
        try {
          fs.unlinkSync(filePath);
        } catch (unlinkError) {
          console.error('删除文件失败:', unlinkError);
        }
      }
    });
    res.status(500).json({ 
      message: '上传失败: ' + error.message,
      results: {
        success: results.success,
        failed: results.failed
      }
    });
  }
});

module.exports = router;